//--------------------------------------
// silk-editor-plugin Project
//
// SilkSourceViewerConfiguraion.java
// Since: 2010/11/15
//
// $URL$ 
// $Author$
//--------------------------------------
package org.xerial.silk.editor.plugin.text;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.dltk.ui.text.AbstractScriptScanner;
import org.eclipse.dltk.ui.text.IColorManager;
import org.eclipse.dltk.ui.text.ScriptPresentationReconciler;
import org.eclipse.dltk.ui.text.ScriptSourceViewerConfiguration;
import org.eclipse.dltk.ui.text.SingleTokenScriptScanner;
import org.eclipse.dltk.ui.text.completion.ContentAssistPreference;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.texteditor.ITextEditor;
import org.xerial.silk.editor.plugin.preferences.SilkContentAssistPreference;

public class SilkSourceViewerConfiguraion extends ScriptSourceViewerConfiguration
{

    // The scanners used to reconcile the script
    private AbstractScriptScanner       nodeScanner, commentScanner, preambleScanner, functionScanner;

    private List<AbstractScriptScanner> scannerSet;

    public SilkSourceViewerConfiguraion(IColorManager colorManager, IPreferenceStore preferenceStore,
            ITextEditor editor, String partitioning) {
        super(colorManager, preferenceStore, editor, partitioning);

    }

    @Override
    protected ContentAssistPreference getContentAssistPreference() {
        return SilkContentAssistPreference.getDefault();
    }

    @Override
    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {

        // Create a presentation reconciler
        PresentationReconciler reconciler = new ScriptPresentationReconciler();
        reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));

        // Create a DefaultDamagerRepairer for the default partition (code)
        DefaultDamagerRepairer dr = new DefaultDamagerRepairer(nodeScanner);
        //reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
        //reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);

        // node scanner
        dr = new DefaultDamagerRepairer(nodeScanner);
        reconciler.setDamager(dr, SilkPartitions.SILK_NODE);
        reconciler.setRepairer(dr, SilkPartitions.SILK_NODE);

        // Create a DefaultDamagerRepairer for comment partitions
        dr = new DefaultDamagerRepairer(commentScanner);
        reconciler.setDamager(dr, SilkPartitions.SILK_COMMENT);
        reconciler.setRepairer(dr, SilkPartitions.SILK_COMMENT);

        // Create a default damage repairer for preamble partitions;
        dr = new DefaultDamagerRepairer(preambleScanner);
        reconciler.setDamager(dr, SilkPartitions.SILK_PREAMBLE);
        reconciler.setRepairer(dr, SilkPartitions.SILK_PREAMBLE);

        // Create a default damage repairer for function partitions;
        dr = new DefaultDamagerRepairer(functionScanner);
        reconciler.setDamager(dr, SilkPartitions.SILK_FUNCTION);
        reconciler.setRepairer(dr, SilkPartitions.SILK_FUNCTION);

        return reconciler;
    }

    @Override
    public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
        return SilkPartitions.PARTITION_TYPES;
    }

    /**
     * Create scanners to analyze text inside partitions
     */
    @Override
    protected void initializeScanners() {

        // Create a scanner for the script code
        nodeScanner = new SilkNodeScanner(getColorManager(), fPreferenceStore);
        //nodeScanner = new SingleTokenScriptScanner(getColorManager(), fPreferenceStore, SilkColor.NodeName.key);

        // Create a scanner for comment partitions
        commentScanner = new SingleTokenScriptScanner(getColorManager(), fPreferenceStore, SilkColor.Comment.key);
        preambleScanner = new SingleTokenScriptScanner(getColorManager(), fPreferenceStore, SilkColor.Preamble.key);
        functionScanner = new SingleTokenScriptScanner(getColorManager(), fPreferenceStore, SilkColor.Function.key);

        if (scannerSet == null)
            scannerSet = new ArrayList<AbstractScriptScanner>();

        scannerSet.add(nodeScanner);
        scannerSet.add(commentScanner);
        scannerSet.add(preambleScanner);
        scannerSet.add(functionScanner);

    }

    @Override
    public boolean affectsTextPresentation(PropertyChangeEvent event) {
        // Kick the scanners to apply the given preference change
        for (AbstractScriptScanner each : scannerSet) {
            if (each.affectsBehavior(event))
                return true;
        }
        return false;
    }

    @Override
    protected IInformationControlCreator getOutlinePresenterControlCreator(ISourceViewer sourceViewer,
            final String commandId) {
        return new IInformationControlCreator() {
            public IInformationControl createInformationControl(Shell parent) {
                int shellStyle = SWT.RESIZE;
                int treeStyle = SWT.V_SCROLL | SWT.H_SCROLL;
                return new SilkOutlineInformationControl(parent, shellStyle, treeStyle, commandId, fPreferenceStore);
            }
        };
    }
}
